{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Transformer(Greedy_decoder)-Torch.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "metadata": {
        "id": "qR7gG-dBsCgk",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1685
        },
        "outputId": "eacfb370-d9c3-4bdb-acb8-dfb8744a8540"
      },
      "cell_type": "code",
      "source": [
        "'''\n",
        "  code by Tae Hwan Jung(Jeff Jung) @graykode, Derek Miller @dmmiller612\n",
        "  Reference : https://github.com/jadore801120/attention-is-all-you-need-pytorch\n",
        "              https://github.com/JayParks/transformer\n",
        "'''\n",
        "import numpy as np\n",
        "import torch\n",
        "import torch.nn as nn\n",
        "import torch.optim as optim\n",
        "from torch.autograd import Variable\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "dtype = torch.FloatTensor\n",
        "# S: Symbol that shows starting of decoding input\n",
        "# E: Symbol that shows starting of decoding output\n",
        "# P: Symbol that will fill in blank sequence if current batch data size is short than time steps\n",
        "sentences = ['ich mochte ein bier P', 'S i want a beer', 'i want a beer E']\n",
        "\n",
        "# Transformer Parameters\n",
        "src_vocab = {w: i for i, w in enumerate(sentences[0].split())}\n",
        "src_vocab_size = len(src_vocab)\n",
        "tgt_vocab = {w: i for i, w in enumerate(set((sentences[1]+' '+sentences[2]).split()))}\n",
        "number_dict = {i: w for i, w in enumerate(set((sentences[1]+' '+sentences[2]).split()))}\n",
        "tgt_vocab_size = len(tgt_vocab)\n",
        "\n",
        "src_len = 5\n",
        "tgt_len = 5\n",
        "\n",
        "d_model = 512  # Embedding Size\n",
        "d_ff = 2048 # FeedForward dimension\n",
        "d_k = d_v = 64  # dimension of K(=Q), V\n",
        "n_layers = 6  # number of Encoder of Decoder Layer\n",
        "n_heads = 8  # number of heads in Multi-Head Attention\n",
        "\n",
        "def make_batch(sentences):\n",
        "    input_batch = [[src_vocab[n] for n in sentences[0].split()]]\n",
        "    output_batch = [[tgt_vocab[n] for n in sentences[1].split()]]\n",
        "    target_batch = [[tgt_vocab[n] for n in sentences[2].split()]]\n",
        "    return Variable(torch.LongTensor(input_batch)), Variable(torch.LongTensor(output_batch)), Variable(torch.LongTensor(target_batch))\n",
        "\n",
        "def get_sinusoid_encoding_table(n_position, d_model):\n",
        "    def cal_angle(position, hid_idx):\n",
        "        return position / np.power(10000, 2 * (hid_idx // 2) / d_model)\n",
        "    def get_posi_angle_vec(position):\n",
        "        return [cal_angle(position, hid_j) for hid_j in range(d_model)]\n",
        "\n",
        "    sinusoid_table = np.array([get_posi_angle_vec(pos_i) for pos_i in range(n_position)])\n",
        "    sinusoid_table[:, 0::2] = np.sin(sinusoid_table[:, 0::2])  # dim 2i\n",
        "    sinusoid_table[:, 1::2] = np.cos(sinusoid_table[:, 1::2])  # dim 2i+1\n",
        "    return torch.FloatTensor(sinusoid_table)\n",
        "\n",
        "def get_attn_pad_mask(seq_q, seq_k):\n",
        "    batch_size, len_q = seq_q.size()\n",
        "    batch_size, len_k = seq_k.size()\n",
        "    pad_attn_mask = seq_k.data.eq(0).unsqueeze(1)  # batch_size x 1 x len_k(=len_q)\n",
        "    return pad_attn_mask.expand(batch_size, len_q, len_k)  # batch_size x len_q x len_k\n",
        "\n",
        "class ScaledDotProductAttention(nn.Module):\n",
        "\n",
        "    def __init__(self):\n",
        "        super(ScaledDotProductAttention, self).__init__()\n",
        "\n",
        "    def forward(self, Q, K, V, attn_mask=None):\n",
        "        scores = torch.matmul(Q, K.transpose(-1, -2)) / np.sqrt(d_k) # scores : [batch_size x n_heads x len_q(=len_k) x len_k(=len_q)]\n",
        "        if attn_mask is not None:\n",
        "            scores.masked_fill_(attn_mask, -1e9)\n",
        "        attn = nn.Softmax(dim=-1)(scores)\n",
        "        context = torch.matmul(attn, V)\n",
        "        return context, attn\n",
        "\n",
        "class MultiHeadAttention(nn.Module):\n",
        "\n",
        "    def __init__(self):\n",
        "        super(MultiHeadAttention, self).__init__()\n",
        "        self.W_Q = nn.Linear(d_model, d_k * n_heads)\n",
        "        self.W_K = nn.Linear(d_model, d_k * n_heads)\n",
        "        self.W_V = nn.Linear(d_model, d_v * n_heads)\n",
        "\n",
        "    def forward(self, Q, K, V, attn_mask=None):\n",
        "        # q: [batch_size x len_q x d_model], k: [batch_size x len_k x d_model], v: [batch_size x len_k x d_model]\n",
        "        residual, batch_size = Q, Q.size(0)\n",
        "        # (B, S, D) -proj-> (B, S, D) -split-> (B, S, H, W) -trans-> (B, H, S, W)\n",
        "        q_s = self.W_Q(Q).view(batch_size, -1, n_heads, d_k).transpose(1,2)  # q_s: [batch_size x n_heads x len_q x d_k]\n",
        "        k_s = self.W_K(K).view(batch_size, -1, n_heads, d_k).transpose(1,2)  # k_s: [batch_size x n_heads x len_k x d_k]\n",
        "        v_s = self.W_V(V).view(batch_size, -1, n_heads, d_v).transpose(1,2)  # v_s: [batch_size x n_heads x len_k x d_v]\n",
        "\n",
        "        if attn_mask is not None: # attn_mask : [batch_size x len_q x len_k]\n",
        "            attn_mask = attn_mask.unsqueeze(1).repeat(1, n_heads, 1, 1) # attn_mask : [batch_size x n_heads x len_q x len_k]\n",
        "        # context: [batch_size x n_heads x len_q x d_v], attn: [batch_size x n_heads x len_q(=len_k) x len_k(=len_q)]\n",
        "        context, attn = ScaledDotProductAttention()(q_s, k_s, v_s, attn_mask=attn_mask)\n",
        "        context = context.transpose(1, 2).contiguous().view(batch_size, -1, n_heads * d_v) # context: [batch_size x len_q x n_heads * d_v]\n",
        "        output = nn.Linear(n_heads * d_v, d_model)(context)\n",
        "        return nn.LayerNorm(d_model)(output + residual), attn # output: [batch_size x len_q x d_model]\n",
        "\n",
        "class PoswiseFeedForwardNet(nn.Module):\n",
        "\n",
        "    def __init__(self):\n",
        "        super(PoswiseFeedForwardNet, self).__init__()\n",
        "        self.conv1 = nn.Conv1d(in_channels=d_model, out_channels=d_ff, kernel_size=1)\n",
        "        self.conv2 = nn.Conv1d(in_channels=d_ff, out_channels=d_model, kernel_size=1)\n",
        "\n",
        "    def forward(self, inputs):\n",
        "        residual = inputs # inputs : [batch_size, len_q, d_model]\n",
        "        output = nn.ReLU()(self.conv1(inputs.transpose(1, 2)))\n",
        "        output = self.conv2(output).transpose(1, 2)\n",
        "        return nn.LayerNorm(d_model)(output + residual)\n",
        "\n",
        "class EncoderLayer(nn.Module):\n",
        "\n",
        "    def __init__(self):\n",
        "        super(EncoderLayer, self).__init__()\n",
        "        self.enc_self_attn = MultiHeadAttention()\n",
        "        self.pos_ffn = PoswiseFeedForwardNet()\n",
        "\n",
        "    def forward(self, enc_inputs):\n",
        "        enc_outputs, attn = self.enc_self_attn(enc_inputs, enc_inputs, enc_inputs) # enc_inputs to same Q,K,V\n",
        "        enc_outputs = self.pos_ffn(enc_outputs) # enc_outputs: [batch_size x len_q x d_model]\n",
        "        return enc_outputs, attn\n",
        "\n",
        "class DecoderLayer(nn.Module):\n",
        "\n",
        "    def __init__(self):\n",
        "        super(DecoderLayer, self).__init__()\n",
        "        self.dec_self_attn = MultiHeadAttention()\n",
        "        self.dec_enc_attn = MultiHeadAttention()\n",
        "        self.pos_ffn = PoswiseFeedForwardNet()\n",
        "\n",
        "    def forward(self, dec_inputs, enc_outputs, enc_attn_mask, dec_attn_mask=None):\n",
        "        dec_outputs, dec_self_attn = self.dec_self_attn(dec_inputs, dec_inputs, dec_inputs, dec_attn_mask)\n",
        "        dec_outputs, dec_enc_attn = self.dec_enc_attn(dec_outputs, enc_outputs, enc_outputs, enc_attn_mask)\n",
        "        dec_outputs = self.pos_ffn(dec_outputs)\n",
        "        return dec_outputs, dec_self_attn, dec_enc_attn\n",
        "\n",
        "class Encoder(nn.Module):\n",
        "\n",
        "    def __init__(self):\n",
        "        super(Encoder, self).__init__()\n",
        "        self.src_emb = nn.Embedding(src_vocab_size, d_model)\n",
        "        self.pos_emb = nn.Embedding.from_pretrained(get_sinusoid_encoding_table(src_len+1 , d_model),freeze=True)\n",
        "        self.layers = nn.ModuleList([EncoderLayer() for _ in range(n_layers)])\n",
        "\n",
        "    def forward(self, enc_inputs): # enc_inputs : [batch_size x source_len]\n",
        "        enc_outputs = self.src_emb(enc_inputs) + self.pos_emb(torch.LongTensor([[1,2,3,4,5]]))\n",
        "        enc_self_attns = []\n",
        "        for layer in self.layers:\n",
        "            enc_outputs, enc_self_attn = layer(enc_outputs)\n",
        "            enc_self_attns.append(enc_self_attn)\n",
        "        return enc_outputs, enc_self_attns\n",
        "\n",
        "class Decoder(nn.Module):\n",
        "\n",
        "    def __init__(self):\n",
        "        super(Decoder, self).__init__()\n",
        "        self.tgt_emb = nn.Embedding(tgt_vocab_size, d_model)\n",
        "        self.pos_emb = nn.Embedding.from_pretrained(get_sinusoid_encoding_table(tgt_len+1 , d_model),freeze=True)\n",
        "        self.layers = nn.ModuleList([DecoderLayer() for _ in range(n_layers)])\n",
        "\n",
        "    def forward(self, dec_inputs, enc_inputs, enc_outputs, dec_attn_mask=None): # dec_inputs : [batch_size x target_len]\n",
        "        dec_outputs = self.tgt_emb(dec_inputs) + self.pos_emb(torch.LongTensor([[1,2,3,4,5]]))\n",
        "        dec_enc_attn_pad_mask = get_attn_pad_mask(dec_inputs, enc_inputs)\n",
        "\n",
        "        dec_self_attns, dec_enc_attns = [], []\n",
        "        for layer in self.layers:\n",
        "            dec_outputs, dec_self_attn, dec_enc_attn = layer(dec_outputs, enc_outputs,\n",
        "                                                             enc_attn_mask=dec_enc_attn_pad_mask,\n",
        "                                                             dec_attn_mask=dec_attn_mask)\n",
        "            dec_self_attns.append(dec_self_attn)\n",
        "            dec_enc_attns.append(dec_enc_attn)\n",
        "        return dec_outputs, dec_self_attns, dec_enc_attns\n",
        "\n",
        "class Transformer(nn.Module):\n",
        "\n",
        "    def __init__(self):\n",
        "        super(Transformer, self).__init__()\n",
        "        self.encoder = Encoder()\n",
        "        self.decoder = Decoder()\n",
        "        self.projection = nn.Linear(d_model, tgt_vocab_size, bias=False)\n",
        "\n",
        "    def forward(self, enc_inputs, dec_inputs, decoder_mask=None):\n",
        "        enc_outputs, enc_self_attns = self.encoder(enc_inputs)\n",
        "        dec_outputs, dec_self_attns, dec_enc_attns = self.decoder(dec_inputs, enc_inputs, enc_outputs, decoder_mask)\n",
        "        dec_logits = self.projection(dec_outputs) # dec_logits : [batch_size x src_vocab_size x tgt_vocab_size]\n",
        "        return dec_logits.view(-1, dec_logits.size(-1)), enc_self_attns, dec_self_attns, dec_enc_attns\n",
        "\n",
        "def greedy_decoder(model, enc_input, start_symbol):\n",
        "    \"\"\"\n",
        "    For simplicity, a Greedy Decoder is Beam search when K=1. This is necessary for inference as we don't know the\n",
        "    target sequence input. Therefore we try to generate the target input word by word, then feed it into the transformer.\n",
        "    Starting Reference: http://nlp.seas.harvard.edu/2018/04/03/attention.html#greedy-decoding\n",
        "    :param model: Transformer Model\n",
        "    :param enc_input: The encoder input\n",
        "    :param start_symbol: The start symbol. In this example it is 'S' which corresponds to index 4\n",
        "    :return: The target input\n",
        "    \"\"\"\n",
        "    memory, attention = model.encoder(enc_input)\n",
        "    dec_input = torch.ones(1, 5).fill_(0).type_as(enc_input.data)\n",
        "    dec_mask = torch.from_numpy(np.triu(np.ones((1, 5, 5)), 1).astype('uint8')) == 0\n",
        "    next_symbol = start_symbol\n",
        "    for i in range(0, 5):\n",
        "        dec_input[0][i] = next_symbol\n",
        "        out = model.decoder(Variable(dec_input), enc_input, memory, dec_mask)\n",
        "        projected = model.projection(out[0])\n",
        "        prob = projected.view(-1, projected.size(-1))\n",
        "        prob = prob.data.max(1, keepdim=True)[1]\n",
        "        next_word = prob.data[i]\n",
        "        next_symbol = next_word[0]\n",
        "    return dec_input\n",
        "\n",
        "def showgraph(attn):\n",
        "    attn = attn[-1].squeeze(0)[0]\n",
        "    attn = attn.squeeze(0).data.numpy()\n",
        "    fig = plt.figure(figsize=(n_heads, n_heads)) # [n_heads, n_heads]\n",
        "    ax = fig.add_subplot(1, 1, 1)\n",
        "    ax.matshow(attn, cmap='viridis')\n",
        "    ax.set_xticklabels(['']+sentences[0].split(), fontdict={'fontsize': 14}, rotation=90)\n",
        "    ax.set_yticklabels(['']+sentences[2].split(), fontdict={'fontsize': 14})\n",
        "    plt.show()\n",
        "\n",
        "model = Transformer()\n",
        "\n",
        "criterion = nn.CrossEntropyLoss()\n",
        "optimizer = optim.Adam(model.parameters(), lr=0.001)\n",
        "\n",
        "for epoch in range(100):\n",
        "\toptimizer.zero_grad()\n",
        "\tenc_inputs, dec_inputs, target_batch = make_batch(sentences)\n",
        "\toutputs, enc_self_attns, dec_self_attns, dec_enc_attns = model(enc_inputs, dec_inputs)\n",
        "\tloss = criterion(outputs, target_batch.contiguous().view(-1))\n",
        "\tif (epoch + 1) % 20 == 0:\n",
        "\t\tprint('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.6f}'.format(loss))\n",
        "\tloss.backward()\n",
        "\toptimizer.step()\n",
        "\n",
        "# Test\n",
        "greedy_dec_input = greedy_decoder(model, enc_inputs, start_symbol=4)\n",
        "predict, _, _, _ = model(enc_inputs, greedy_dec_input)\n",
        "predict = predict.data.max(1, keepdim=True)[1]\n",
        "print(sentences[0], '->', [number_dict[n.item()] for n in predict.squeeze()])\n",
        "\n",
        "print('first head of last state enc_self_attns')\n",
        "showgraph(enc_self_attns)\n",
        "\n",
        "print('first head of last state dec_self_attns')\n",
        "showgraph(dec_self_attns)\n",
        "\n",
        "print('first head of last state dec_enc_attns')\n",
        "showgraph(dec_enc_attns)"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Epoch: 0020 cost = 0.371343\n",
            "Epoch: 0040 cost = 0.001501\n",
            "Epoch: 0060 cost = 0.039111\n",
            "Epoch: 0080 cost = 1.864157\n",
            "Epoch: 0100 cost = 0.007700\n",
            "ich mochte ein bier P -> ['i', 'i', 'want', 'a', 'beer']\n",
            "first head of last state enc_self_attns\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeYAAAH2CAYAAAClRS9UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAHHxJREFUeJzt3XuQ1QX9//H3LhdxSmF+KKLQIiFp\nE2iACBQFEeovNKLQDAFrS9Ca1MREXaf4YgphdlPT8ZJhZt6CmrwMCnjJ0lTERjARoeUeZiQ6S1yU\nPb8/HPf7Y8A4yMLnfejx+Gv3c/by2h12n5zPOXtOValUKgUAkEJ10QMAgP8lzACQiDADQCLCDACJ\nCDMAJCLMAJCIMANAIsIMAIkIMxXjjTfeiLvvvjt++tOfNh1btmxZcYMA9gBhpiI8+eSTMXjw4PjV\nr34VN998c0RErF69Oj7/+c/Ho48+Wuw4gGYkzFSEH/zgB3HJJZfE73//+6iqqoqIiE6dOsVVV121\nzTVogEonzFSEv/3tb/GFL3whIqIpzBERn/rUp5zOBvYpwkxF6NChQ6xatWq7488991wccMABBSwC\n2DNaFj0AyjF8+PAYP358nHHGGdHY2BizZs2KRYsWxR133BFnnHFG0fMAmk2Vp32kEpRKpbj11lvj\nN7/5TaxYsSLatGkTNTU1MWrUqBg5cmTR8wCajTBTEZYvXx5dunTZ7viWLVtiwYIF0adPnwJWATQ/\ntzFTEYYPH77D4//+97/jzDPP3MtrAPYctzGT2t133x133XVXvPnmm3HKKadsd/k///nPaNeuXQHL\nAPYMYSa1z3zmM9G2bduYMGFCDB48eLvL99tvvxg6dOjeHwawh7iNmYpw//33x0knnVT0DIA9Tpip\nGH/5y19iyZIlsXnz5u0uGz16dAGLAJqfMFMRrrjiirjtttuiffv2sd9++21zWVVVVcydO7egZQDN\nS5ipCL169Yprr702Pv7xjxc9BWCP8udSVIQDDjgg+vbtW/QMgD1OmKkI5557btxyyy3hBA+wr3Mq\nm7RGjhy5zTNJrVy5Mlq0aBGHHnroNscjIn7zm9/s7XkAe4S/YyatT33qU0VPANjrXGOmomzdujVa\ntGgREREbN26M/fffv+BFAM3LbcxUhGXLlsVnP/vZmD17dtOxO+64I04++eRYvnx5gcsAmpcwUxEm\nT54cxx13XAwYMKDp2Kmnnhqf+MQnYvLkyQUuA2heTmVTEfr06RNPPfVUtGy57d0i3nzzzejfv388\n++yzBS2Dd7dq1aro3Llz0TOoMK4xUxHatm0bS5Ys2e74ggUL4v3vf38Bi2Dnhg8fHlu3bi16BhXG\nvbKpCGeccUbU1tbGsGHDonPnztHY2Bj19fUxa9asuPDCC4ueBzs0evTouPrqq2PcuHH+A0nZnMqm\nYsyZMydmzpwZK1eujKqqqvjABz4QI0eOjCFDhhQ9DXboM5/5TPzzn/+MDRs2xPvf//6mvyh4x5NP\nPlnQMjITZoA95Le//e1/vPzzn//8XlpCJRFmKsbMmTPjgQceiNWrV0dVVVXU1NTEyJEj4/jjjy96\nGuzUm2++Ga1atSp6BhXAbcx7wNatW2PLli3bHfdgGO/dddddF7feemsMGzYsBg4cGBERf/vb3+Li\niy+ODRs2xIgRIwpeWLleeeWVmD59eixdujQ2bdq03eW//OUvC1i1b9iyZUv87Gc/ixkzZsTrr78e\nCxYsiIaGhrj88svjO9/5Trzvfe8reiIJCXMzevLJJ2Py5MmxYsWKHT7ZwosvvljAqn3DPffcEzfc\ncEN89KMf3eb48OHDY/LkycK8G84///xYv3599OvXL9q0aVP0nH3KFVdcES+88EJ897vfjW9/+9sR\nEdHY2BivvfZaTJkyJa644oqCF5KRMDejSy65JAYMGBB1dXV+wTWz9evXR8+ePbc73qtXr1i9enUB\ni/YdL774YjzyyCPRrl27oqfscx566KH47W9/Gx07dmx64pUDDzwwpk6dGsOHDy94HVkJczN6/fXX\nY/LkydG6deuip+xzDj/88Jg7d26ccMIJ2xx/5JFHPIDDbjr88MP9re0esnXr1jj44IO3O966devY\nsGFDAYuoBMLcjIYMGRKLFi2Ko48+uugp+5xzzjknzjnnnOjXr19069YtIt6+jfmpp56KqVOnFryu\nsl144YVx6aWXxmmnnRadOnWK6uptH3foiCOOKGhZ5fvIRz4SN910U5x99tlNxzZs2BDf//73/Z7g\nXblX9m66/fbbm17euHFjzJgxIwYPHrzDa3GjR4/em9P2OYsXL44ZM2bEypUrY8uWLVFTUxMjRozw\nC243HXXUUdsdq6qqilKpFFVVVe4bsRsWL14cZ555Zrz11lvx2muvxQc/+MFYvXp1HHzwwXHddddF\n9+7di55IQsK8m8p9cIuqqqqYO3fuHl4Du25nt9F36tRpLy3ZN23atCkeeeSRWLlyZbRp0ya6dOkS\nAwcO3O7BRuAdwkxFWLVqVUyfPj2WL18emzdv3u5yf9ID7CvcxtyMSqVSTJ8+PXr37h3HHHNMREQ8\n+OCDsWrVqqitrd3utjvKd+6558abb74Zxx13nDvXNYPBgwfHo48+GhER/fv3b7rH8I542Mhd43vL\n7hLmZnTllVfGnDlz4thjj206dtBBB8U111wT69ati4kTJxa4rrLV19fHH//4Rw/I0EzOP//8ppcv\nuuiiiIj497//Ha1bt97uqTXZNe/2vW3VqlW8+uqr0aFDB9/j3bR06dJ49NFHo0WLFjF06NB97i8z\nnMpuRgMHDowZM2bEIYccss3xV155JU455ZR4/PHHC1pW+c4+++z45je/GT169Ch6yj5n/fr18b3v\nfS9mzZoVVVVVsXDhwvjXv/4V5513Xvzwhz+MDh06FD2xYq1ZsyYuuuiiePbZZ6NUKkWpVIqWLVvG\noEGDYtKkSb6378ETTzwRZ511Vhx++OHR2NgYa9asiVtuuSV69epV9LRmI8zN6Nhjj43HHntsu2t1\n69evjyFDhsT8+fMLWlb51q5dG7W1tfHhD384DjnkkO1ODzob8d5dcMEF0dDQEOeee26MGjUqnn/+\n+di0aVNcdtll0dDQEFdffXXREyvW2LFjo1WrVvHVr341ampqolQqxfLly+PWW2+NUqkUt9xyS9ET\nK86oUaPipJNOijFjxkRExG233RYPPfRQ3HbbbQUvaz7OpzSjgQMHxiWXXBJnnXVWdOrUqek5g6+7\n7roYPHhw0fMq2qWXXhpr166NAw88MF599dVtLvtPt+Gxc3/4wx9i9uzZ0a5du6bvZZs2baKuri6G\nDh1a8LrKtnDhwnj88ce3eS7mLl26RO/eveOTn/xkgcsq15IlS+KLX/xi0+unnHJKXHvttQUuan7C\n3IwmTZoUl156aZx66qlNp62qq6tj6NCh8b3vfa/oeRVt3rx58cADD/jTnT2gZcuWO3wI2S1btuzw\nHvCUr6amJhoaGrYJc8Tbj3ng3/J7s2XLlm3uALr//vvv8MlXKpkw76alS5c2PRLVunXrYsKECU33\nwH7nVoJ27drF3//+d4+gtBu6d+8e++23X9Ez9km9evWKadOmNT3JQkTEihUr4vLLL48BAwYUuKwy\nLVmypOnl2tramDBhQpx++unRrVu3qKqqivr6+rjjjjviG9/4RoErycxtzLvp6KOPjueffz4i3n4E\npR2dVvUISrvvvvvuizvvvDNOOumk6Nix43Z/ejZo0KCCllW+tWvXxte//vVYvHhxbN26Ndq0aROb\nN2+OY489Nq666qrt7szIf/bO74Gd/Wr1O+G96dGjR9TV1W3z/Z06dep2xyr5kRaFeTetWbMmDjvs\nsIjwCEp70o4eNvIdfsE1jwULFsTKlStjv/32iy5dujjD8x7tyrOd+Z2w68p5tMVKf6RFYQaARDwU\nFQAkIswAkIgwA0AiwgwAiQgzACRScQ8wcnz1qUVPKNuNz/8wxh99QdEzyrb4hr5FTyjbQyNr44QZ\nvyh6RtnaP1M5P2p3Tzojvji5cp7fet5l1xc9oWxV7e+P0rqTip5Rtm5za4ueULZZJ42L/3v/TUXP\nKFv96Lp3vcw15j2oa4+aoifss478PwcXPWGfdUSng4qesM+qavWhoifss45st+/8ThBmAEhEmAEg\nEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESE\nGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYA\nSESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEkkV5tWrV0fPnj1jyZIlRU8BgEK0LHrA/69T\np06xYMGComcAQGFSXWMGgP92qcK8atWqOPLII2Px4sVFTwGAQqQKMwD8t6sqlUqloke8Y9WqVfHp\nT3867r333vjQhz60w7epX7giuvao2cvLAGDvSHXnr3KMP/qCoieUbXbjPXF89alFzyjb4hv6Fj2h\nbMvHTYwuN11Z9IyytX+mcn7U5t84IXqP/1HRM8o277Lri55QtuqOL0fj2u5Fzyhbt7m1RU8oW/3o\nuuh6+5SiZ5StfnTdu17mVDYAJCLMAJCIMANAIsIMAImkukdK586d46WXXip6BgAUxjVmAEhEmAEg\nEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESE\nGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYA\nSESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASAR\nYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZ\nABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBI\nRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASSRPmmTNnxrp164qeAQCFShHmrVu3xtSpU4UZ\ngP96Ow3z4MGDY/bs2U2vn3nmmTFs2LCm1xctWhQ9e/aMpUuXxllnnRX9+vWLvn37xte//vX4xz/+\n0fR2Rx55ZDz44IMxatSo+OhHPxrDhw+Pl156KSIi+vTpE2+88UZ84QtfiJ/85CfN+fUBQEXZaZj7\n9esX8+fPj4i3r9m+8MILsWnTpnjttdciImLevHnRq1evuOyyy+KAAw6Ixx9/PB5++OFoaGiIadOm\nbfOxbr755pgyZUo88cQT0bZt27jmmmsiIuK+++6LiLdPZ3/rW99q1i8QACpJy529Qf/+/eOuu+6K\niIgXXnghunTpEh07doxnn302hg4dGvPmzYsBAwZEbW1tRES0bt06WrduHUOGDIk777xzm4918skn\nR9euXSMi4pOf/GTMnDlzlwff+PwPo2uPml1+v6LMbryn6An7rOXjJhY9oXzjih6wa+bfOKHoCbug\nkrZGVHd8uegJZasfXfSCXVM/uq7oCc2irDB/5zvfic2bN8czzzwTxx57bHTo0GGbMNfW1sbChQvj\nxz/+cSxatCi2bNkSjY2Nccghh2zzsTp37tz08v777x+bN2/e5cHjj75gl9+nKLMb74njq08tekbZ\nFt/Qt+gJZVs+bmJ0uenKomeUrf0zO/1RS2P+jROi9/gfFT2jbPMuu77oCWWr7vhyNK7tXvSMsnWb\nW1v0hLLVj66LrrdPKXpG2f7TfyJ2eir70EMPjcMOOywWLFgQzzzzTPTp0yd69eoVzz77bKxYsSI2\nbdoUNTU1MX78+OjRo0c88sgjsWDBgpg4cftrM9XVKe5rBgBplVXK/v37x7x58+K5556L3r17x4c/\n/OGor6+PP/7xj3HcccfFsmXLYsOGDfG1r30tDjzwwIh4+7Q3ALBryg7z7373u+jQoUO0bds2WrZs\n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\n",
            "text/plain": [
              "<Figure size 576x576 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "first head of last state dec_self_attns\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nZsyI7t27Fz2RhIT5ENX3yS3Kyspi0aJFTbwGGu5g99F36dLlMC1pnnbt2hVPP/10bNq0Kdq2bRvd\nunWLgQMH7vNkI/ARYaYkbN68OWbOnBmvvfZa7N69e5/L/UkP0Fy4j7kR1dbWxsyZM6N3795xxhln\nRETEggULYvPmzVFRUbHPfXfU37XXXhvvv/9+nHXWWR5c1wgGDx4czzzzTERE9O/fv+4Rw/vjaSMb\nxnXLoRLmRnTXXXfFU089FX379q07dvTRR8d9990Xb731VkyaNKnAdaWtsrIyfvvb33pChkYyYcKE\nurcnT54cERHvvfdetGnTZp+X1qRhDnTdtm7dOt54443o2LGj6/gQrV+/Pp555plo2bJlDB06tNn9\nZYZT2Y1o4MCBMXfu3OjUqdNex19//fUYOXJkPPfccwUtK31XXnllfOMb34gePXoUPaXZefvtt+O2\n226L+fPnR1lZWaxcuTL++Mc/xnXXXRff+973omPHjkVPLFlbt26NyZMnx/Lly6O2tjZqa2ujVatW\nMWjQoLj11ltdtx/D4sWLY/z48XHCCSdETU1NbN26NR5++OHo1atX0dMajTA3or59+8azzz67z626\nt99+O4YMGRLPP/98QctK37Zt26KioiJOO+206NSp0z6nB52N+Piuv/76qKqqimuvvTZGjx4dL730\nUuzatSu+853vRFVVVdx7771FTyxZY8eOjdatW8dll10W5eXlUVtbG6+99lo88sgjUVtbGw8//HDR\nE0vO6NGj4/zzz48xY8ZERMSsWbPiV7/6VcyaNavgZY3H+ZRGNHDgwLj55ptj/Pjx0aVLl7rXDJ4x\nY0YMHjy46Hkl7ZZbbolt27bFUUcdFW+88cZel/2p+/A4uN/85jexcOHC6NChQ9112bZt25gyZUoM\nHTq04HWlbeXKlfHcc8/t9VrM3bp1i969e8eXvvSlApeVrnXr1sXXv/71uvdHjhwZ999/f4GLGp8w\nN6Jbb701brnllhg1alTdaasWLVrE0KFD47bbbit6XklbtmxZPPnkk/50pwm0atVqv08hu2fPnv0+\nAp76Ky8vj6qqqr3CHPHhcx74t/zx7NmzZ68HgB555JH7ffGVUibMh2j9+vV1z0T11ltvxcSJE+se\ngf3RvQQdOnSI//7v//YMSoege/fuccQRRxQ9o1nq1atXTJ8+ve5FFiIiNm7cGLfffnsMGDCgwGWl\n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\nABSqsDCfccYZ8Td/8zdRUVER5557brRu3TruvPPOePfdd53SBuATq9AHf910001x00037XVs8eLF\nBa0BgOK5QxcAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBE\nhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFm\nAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEmlV9ICGOvqf\nlxQ9of7+qbT2Hl30gIa4OqL7N5YWvaLeaooe0EA1u3YVPaH+Vr9S9IIGqS6hvQu2vlj0hAYptb0H\n4hYzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQi\nzACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDAD\nQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACRS7zBv3rw5TjnllFi7\ndm1T7gGATzS3mAEgEWEGgEQaHOb/+q//iuHDh0evXr1izJgxsWXLloiI+N3vfhd/9Vd/Fb17946B\nAwfGPffcEzU1NXWf96//+q8xbNiwOOOMM+Lcc8+NJ598su6ysWPHxvTp02PEiBHx13/9143wYwFA\naWpwmB977LF44IEH4tlnn43WrVvH5MmTY9u2bTF+/PgYOXJk/O53v4uZM2fGL37xi5gzZ05ERDz1\n1FPx/e9/P7773e/G888/HzfddFNMmjQp1q9fX/d1f/nLX8att94aM2fObLQfDgBKTVltbW1tfT5w\n8+bNcfbZZ8ddd90Vf/mXfxkREc8991xcccUVcc0118SiRYti3rx5dR//ox/9KObPnx+zZ8+OcePG\nxUknnRSTJ0+uu/zKK6+M7t27x/XXXx9jx46No446Kn7wgx8cdEflyo1xYo/yhv6cAFASWjX0E04+\n+eS6t8vLy6O2tjaWLl0aq1evjtNPP73ustra2jj66KMjImLjxo3xH//xH/GTn/xkr8vbtWtX9/5x\nxx1Xr+8/ruf1DZ1cmIU1j8c5LUYVPaNZct02Hddt0ym163bB1heLnlBvLTq/EjXbuhc9o95adH7l\ngJc1OMwtWvzP2e+Pbmx36dIl2rRpEw899NB+P6dt27Zx3XXXxbhx4w48pFWDpwBAs9Pg+5grKyvr\n3t64cWO0bNkyTj311HjllVf2erDXW2+9Fbt27YqID29Zv/zyy3t9na1bt+718QDAxwjzo48+Gn/4\nwx+iqqoqHnnkkRg0aFCMGDEiqqqq4r777oudO3fG1q1b44orrogHH3wwIiJGjx4dCxYsiKeeeio+\n+OCDeP7552PEiBGxdOnSRv+BAKCUNTjMo0ePjssuuyy++MUvxgcffBB/93d/F+3bt48HHnggfvOb\n30S/fv3ioosuijPPPDOuvvrqiIgYMGBATJkyJaZNmxa9e/eOKVOmxI033hgDBgxo9B8IAEpZve/Y\n7dq1a93p6GHDhu1z+VlnnRVz58494OdffPHFcfHFF+/3slmzZtV3BgA0a575CwASEWYASESYASAR\nYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZ\nABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBI\nRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFh\nBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkA\nEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhE\nmAEgEWEGgESEGQASEWYASESYASARYQaARFoV8U2HDBkSr7/+erRose//C6ZMmRKjR48uYBUAFK+Q\nMEdE3HzzzTFmzJiivj0ApORUNgAkIswAkEhZbW1t7eH+pn/qPuYXX3wxWrZsecDPrVy5MU7sUd6U\n8wCgMCV3H/O4ntc3wZqmsbDm8TinxaiiZzRLrtum47ptOqV23S7Y+mLRE+qtRedXomZb96Jn1FuL\nzq8c+LLDuAMAOAhhBoBEhBkAEinsPuZp06bF9OnT9zk+aNCguP/++wtYBADFKyTMv/71r4v4tgCQ\nnlPZAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCI\nMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIM\nAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJBIWW1tbW3RIwCAD7nF\nDACJCDMAJCLMAJCIMANAIsIMAIkIMwAk8v8AQonJKctA10MAAAAASUVORK5CYII=\n",
            "text/plain": [
              "<Figure size 576x576 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "first head of last state dec_enc_attns\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeYAAAH2CAYAAAClRS9UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAGx9JREFUeJzt3XmMVfX5+PFnhtVUhKSKCDpo1a+a\nAgqoQIuCBDUuJShYpYotVnFJXamIGOsXN7TVWJdirNZA1bqiplUjgruVuhPBqiwOshUXKppBFmXu\n7w/jfH8ElEFmOM8dX6+/Zs5l5j73E3Lfc88599yKUqlUCgAghcqiBwAA/o8wA0AiwgwAiQgzACQi\nzACQiDADQCLCDACJCDMAJCLMlI3PPvss7rvvvrj++uvrts2fP7+4gQAagTBTFqZPnx79+/ePO++8\nM2677baIiFi8eHEcddRR8cwzzxQ7HEADEmbKwh/+8Ie48MIL4+9//3tUVFRERESnTp3immuuWecV\nNEC5E2bKwnvvvRdHH310RERdmCMiDjroILuzgSZFmCkL7du3j0WLFq23/Y033og2bdoUMBFA42he\n9ABQH4MGDYqRI0fGiSeeGLW1tfH444/HO++8E3fffXeceOKJRY8H0GAqfOwj5aBUKsWkSZPigQce\niAULFkTr1q2jqqoqhg0bFkOGDCl6PIAGI8yUhffffz86d+683vY1a9bEzJkzo2fPngVMBdDwHGOm\nLAwaNGiD2z///PM4+eSTt/A0AI3HMWZSu+++++Lee++NL774IoYOHbre7R9//HG0a9eugMkAGocw\nk9phhx0Wbdu2jfPOOy/69++/3u2tWrWKgQMHbvnBABqJY8yUhUcffTSOOOKIoscAaHTCTNmYMWNG\nzJ07N1avXr3ebccff3wBEwE0PGGmLFxxxRVxxx13xA9/+MNo1arVOrdVVFTEk08+WdBkAA1LmCkL\n3bt3j5tuuil++tOfFj0KQKPydinKQps2bWK//fYregyARifMlIWzzjorbr/99rCDB2jq7MomrSFD\nhqzzSVILFy6MZs2axQ477LDO9oiIBx54YEuPB9AovI+ZtA466KCiRwDY4rxipqysXbs2mjVrFhER\nK1eujK222qrgiQAalmPMlIX58+fHz372s5g6dWrdtrvvvjuOPPLIeP/99wucDKBhCTNlYdy4cbH/\n/vtHnz596rYdc8wxccABB8S4ceMKnAygYdmVTVno2bNnvPTSS9G8+bqnRXzxxRfRu3fveO211wqa\nDL7ZokWLYscddyx6DMqMV8yUhbZt28bcuXPX2z5z5szYeuutC5gINm7QoEGxdu3aosegzDgrm7Jw\n4oknxogRI+Lwww+PHXfcMWpra6O6ujoef/zxOP/884seDzbo+OOPjxtuuCFOOeUUf0BSb3ZlUzam\nTZsWDz74YCxcuDAqKipip512iiFDhsSAAQOKHg026LDDDouPP/44VqxYEVtvvXXdOwq+Nn369IIm\nIzNhBmgkDz300LfeftRRR22hSSgnwkzZePDBB+Oxxx6LxYsXR0VFRVRVVcWQIUPi4IMPLno02Kgv\nvvgiWrRoUfQYlAHHmBvB2rVrY82aNettdzGM727ChAkxadKkOPzww6Nv374REfHee+/FmDFjYsWK\nFTF48OCCJyxfH3zwQUycODHmzZsXq1atWu/2v/71rwVM1TSsWbMm/vSnP8XkyZPj008/jZkzZ0ZN\nTU1cfvnlcfHFF8cPfvCDokckIWFuQNOnT49x48bFggULNvhhC2+//XYBUzUN999/f9xyyy2xzz77\nrLN90KBBMW7cOGHeDOeee24sX748evXqFa1bty56nCbliiuuiLfeeit+97vfxW9/+9uIiKitrY1P\nPvkkrrzyyrjiiisKnpCMhLkBXXjhhdGnT58YO3asJ7gGtnz58ujatet627t37x6LFy8uYKKm4+23\n346nn3462rVrV/QoTc4TTzwRDz30UHTo0KHug1e22WabGD9+fAwaNKjg6chKmBvQp59+GuPGjYuW\nLVsWPUqTs/POO8eTTz4ZhxxyyDrbn376aRdw2Ew777yz99o2krVr18Z222233vaWLVvGihUrCpiI\nciDMDWjAgAHxzjvvRLdu3Yoepck588wz48wzz4xevXrFrrvuGhFfHWN+6aWXYvz48QVPV97OP//8\nuOiii+LYY4+NTp06RWXlutcd2m233QqarPz9+Mc/jltvvTVOO+20um0rVqyIq666yvME38hZ2Zvp\nrrvuqvt65cqVMXny5Ojfv/8GX8Udf/zxW3K0Jmf27NkxefLkWLhwYaxZsyaqqqpi8ODBnuA20557\n7rnetoqKiiiVSlFRUeHciM0we/bsOPnkk+PLL7+MTz75JH70ox/F4sWLY7vttosJEybE7rvvXvSI\n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\nmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEG\ngESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIJE0YX7wwQdj2bJlRY8BAIVKEea1a9fG+PHj\nhRmA772Nhrl///4xderUuu9PPvnkOPzww+u+f+edd6Jr164xb968OPXUU6NXr16x3377xemnnx4f\nfvhh3b/bY489YsqUKTFs2LDYZ599YtCgQfHuu+9GRETPnj3js88+i6OPPjr++Mc/NuTjA4CystEw\n9+rVK15//fWI+OqV7VtvvRWrVq2KTz75JCIiXn311ejevXtceuml0aZNm3j++efjqaeeipqamrj6\n6qvX+V233XZbXHnllfHiiy9G27Zt48Ybb4yIiEceeSQivtqdfc455zToAwSActJ8Y/+gd+/ece+9\n90ZExFtvvRWdO3eODh06xGuvvRYDBw6MV199Nfr06RMjRoyIiIiWLVtGy5YtY8CAAXHPPfes87uO\nPPLI2GWXXSIi4sADD4wHH3xwkwf+85vXxi5dqjb554oytfb+okdosio7zCl6hCbL2jYea9t4msra\n1ivMF198caxevTpeeeWV2HfffaN9+/brhHnEiBExa9asuO666+Kdd96JNWvWRG1tbWy//fbr/K4d\nd9yx7uutttoqVq9evckDj+w2apN/pihTa++PgyuPKXqMepuyZEbRI9RbZYc5Ubt096LHaJKsbeOx\nto2n3Nb22/6I2Oiu7B122CE6duwYM2fOjFdeeSV69uwZ3bt3j9deey0WLFgQq1atiqqqqhg5cmR0\n6dIlnn766Zg5c2aMHj16/TurTHGuGQCkVa9S9u7dO1599dV44403okePHrHXXntFdXV1vPDCC7H/\n/vvH/PnzY8WKFfHrX/86ttlmm4j4arc3ALBp6h3mhx9+ONq3bx9t27aN5s2bx5577hl33XVX9OnT\nJzp27BiVlZXxxhtvxMqVK+Pee++N6urq+PTTT2PVqlUb/f2tW7eOiIj58+dHTU3N5j0iAChj9Qpz\nr169Yv78+dGzZ8+6bT169Ii5c+fGT37yk9h+++1j9OjRcckll0S/fv1i3rx5ccMNN0S7du3ikEMO\n2ejv33bbbePQQw+N8847L6655prv/mgAoMxVlEqlUtFDbIpyOpnKyV+Np9xO9Cgn1rbxWNvGU25r\nu1knfwEAW44wA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswA\nkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0Ai\nwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgz\nACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQ\niDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLC\nDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCKFhvmtt96K\n4cOHx3777Re9e/eO0aNHR01NTZEjAUChCg3zOeecE3vvvXf861//ikceeSRmzZoVt956a5EjAUCh\nKkqlUqmoO1+xYkW0aNEiWrZsGRERl19+eVRXV8df/vKXb/yZ6lkLYpcuVVtqRADYopoXeefTp0+P\nCRMmRHV1dXz55Zexdu3a6Nmz57f+zMhuo7bQdJtvau39cXDlMUWPUW9TlswoeoR6q+wwJ2qX7l70\nGE2StW081rbxlNvaVnaY8823bcE51jFv3rw4++yz48gjj4wXX3wxZs6cGSeccEJR4wBACoW9Yn77\n7bejWbNmMWLEiKioqIiIr04Gq6x0ojgA31+FVXCnnXaKNWvWxKxZs6KmpiZuuummWLlyZXz00Uex\ndu3aosYCgEIVFua99947fvWrX8WIESPi0EMPjRYtWsSVV14Zn332mV3aAHxvFXry15gxY2LMmDHr\nbHvxxRcLmgYAiueALgAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANA\nIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkI\nMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswA\nkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0Ai\n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\n",
            "text/plain": [
              "<Figure size 576x576 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    }
  ]
}